package org.siteanalyser.service.impl;

import java.io.IOException;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.siteanalyser.domain.Message;
import org.siteanalyser.service.Service;
import org.siteanalyser.service.SystemException;
import org.springframework.beans.factory.annotation.Required;

/**
 - The class must be able to add multiple error messages to the message report
 - The class must be able to add multiple warn messages to the message report
 - Messages must be added sequentially. For example, if there are 4 error messages, they should be added with the keys 
   w3c.error.1, w3c.error.2, etc.
 - A total count must be added to the message report. For example, if there are 4 error messages, the key 
   w3c.error.count must be set to 4
 - If no error or warning messages are encountered, no keys should be added to the message report
 */
public class W3cValidationServiceImpl implements Service {

    private String baseUrl;

    public void process(final Message message) throws SystemException {
        makeRequest(message);
    }

    private void makeRequest(final Message message) {
        final String siteNameToCheck = message.getRequest().getUrl();
        Document doc = null;
        try {
            doc = Jsoup.connect(baseUrl+siteNameToCheck).get();
        } catch (final IOException e) {
        	// w3c validation site not accessible
            throw new SystemException(e.getMessage());
        }
        if (doc == null) {
            throw new SystemException(String.format("Unable to parse URL: %s", baseUrl+siteNameToCheck));
        }
        // at this moment we have w3c validation response
        // errors
        Elements errors = doc.getElementsByClass("msg_err");
        int i = 0;
        for(Element error : errors) {
            if(!error.getElementsContainingOwnText("Line").isEmpty() && 
                    !error.getElementsByClass("msg").isEmpty()) {
	        	i++;
	        	String msg = error.getElementsContainingOwnText("Line").first().ownText() + ": ";
	        	msg += error.getElementsByClass("msg").first().ownText();
	            message.getReport().addReportItem("w3c.error."+i, msg);
            }
        }
        if(i > 0) {
        	// we have errors
            message.getReport().addReportItem("w3c.error.count", i);
        }
        // warnings
        Elements warns = doc.getElementsByClass("msg_warn");
        i = 0;
        for(Element warn : warns) {
            if(!warn.getElementsContainingOwnText("Line").isEmpty() && 
               !warn.getElementsByClass("msg").isEmpty()) {
		    	i++;
		    	String msg = warn.getElementsContainingOwnText("Line").first().ownText() + ": ";
		    	msg += warn.getElementsByClass("msg").first().ownText();
		        message.getReport().addReportItem("w3c.warn."+i, msg);
            }
        }
        if(i > 0) {
        	// we have warnings
            message.getReport().addReportItem("w3c.warn.count", i);
        }
    }

    @Required
    public void setBaseUrl(final String baseUrl) {
        this.baseUrl = baseUrl;
    }

    public String getBaseUrl() {
        return baseUrl;
    }
}
